﻿namespace System.Workflow.ComponentModel.Compiler
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Workflow.Interop;

    internal static class MetaDataReader
    {
        internal static IEnumerable GetTypeRefNames(string assemblyLocation)
        {
            return new <GetTypeRefNames>d__0(-2) { <>3__assemblyLocation = assemblyLocation };
        }

        private static MetadataTokenType TokenTypeFromToken(uint token)
        {
            return (((MetadataTokenType) token) & ((MetadataTokenType) (-16777216)));
        }

        [CompilerGenerated]
        private sealed class <GetTypeRefNames>d__0 : IEnumerable<object>, IEnumerable, IEnumerator<object>, IEnumerator, IDisposable
        {
            private int <>1__state;
            private object <>2__current;
            public string <>3__assemblyLocation;
            private int <>l__initialThreadId;
            public MetaDataReader.AssemblyMetadata <assemblyMetadata>5__e;
            public IntPtr <assemblyName>5__11;
            public uint <assemblyNameSize>5__12;
            public uint <assemblyRefFlags>5__15;
            public IntPtr <enumHandle>5__5;
            public Guid <guidMetaDataImport>5__2;
            public IntPtr <hashValueBlob>5__13;
            public uint <hashValueSize>5__14;
            public MetaDataReader.IMetaDataAssemblyImport <metaDataAssemblyImport>5__d;
            public MetaDataReader.IMetaDataDispenser <metaDataDispenser>5__1;
            public MetaDataReader.IMetaDataImport <metaDataImport>5__4;
            public object <metaDataImportObj>5__3;
            public IntPtr <publicKeyOrToken>5__f;
            public uint <publicKeyOrTokenSize>5__10;
            public string <publicKeyString>5__16;
            public uint <resolutionScopeToken>5__b;
            public uint <typeRefCount>5__7;
            public int <typeRefIndex>5__8;
            public string <typeRefName>5__c;
            public uint <typeRefNameLength>5__a;
            public IntPtr <typeRefNamePtr>5__9;
            public uint[] <typeRefs>5__6;
            public string assemblyLocation;

            [DebuggerHidden]
            public <GetTypeRefNames>d__0(int <>1__state)
            {
                this.<>1__state = <>1__state;
                this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
            }

            private void <>m__Finally17()
            {
                this.<>1__state = -1;
                this.<metaDataImport>5__4.CloseEnum(this.<enumHandle>5__5);
            }

            private void <>m__Finally18()
            {
                this.<>1__state = 1;
                if ((this.<assemblyName>5__11 != IntPtr.Zero) && (this.<assemblyNameSize>5__12 > 0))
                {
                    Marshal.FreeCoTaskMem(this.<assemblyName>5__11);
                    this.<assemblyName>5__11 = IntPtr.Zero;
                }
                if ((this.<assemblyMetadata>5__e.locale != IntPtr.Zero) && (this.<assemblyMetadata>5__e.localeSize > 0))
                {
                    Marshal.FreeCoTaskMem(this.<assemblyMetadata>5__e.locale);
                    this.<assemblyMetadata>5__e.locale = IntPtr.Zero;
                }
            }

            private bool MoveNext()
            {
                try
                {
                    switch (this.<>1__state)
                    {
                        case 0:
                            this.<>1__state = -1;
                            this.<metaDataDispenser>5__1 = new MetaDataReader.MetaDataDispenser() as MetaDataReader.IMetaDataDispenser;
                            if (this.<metaDataDispenser>5__1 == null)
                            {
                                throw new InvalidOperationException(string.Format(SR.GetString("Error_MetaDataInterfaceMissing"), this.assemblyLocation, "IMetaDataDispenser"));
                            }
                            this.<guidMetaDataImport>5__2 = new Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44");
                            this.<metaDataImportObj>5__3 = null;
                            NativeMethods.ThrowOnFailure(this.<metaDataDispenser>5__1.OpenScope(this.assemblyLocation, 0, ref this.<guidMetaDataImport>5__2, out this.<metaDataImportObj>5__3));
                            this.<metaDataImport>5__4 = this.<metaDataImportObj>5__3 as MetaDataReader.IMetaDataImport;
                            if (this.<metaDataImport>5__4 == null)
                            {
                                throw new InvalidOperationException(string.Format(SR.GetString("Error_MetaDataInterfaceMissing"), this.assemblyLocation, "IMetaDataImport"));
                            }
                            this.<enumHandle>5__5 = new IntPtr();
                            this.<typeRefs>5__6 = new uint[20];
                            this.<typeRefCount>5__7 = 0;
                            this.<>1__state = 1;
                            do
                            {
                                NativeMethods.ThrowOnFailure(this.<metaDataImport>5__4.EnumTypeRefs(ref this.<enumHandle>5__5, this.<typeRefs>5__6, (uint) this.<typeRefs>5__6.Length, ref this.<typeRefCount>5__7));
                                this.<typeRefIndex>5__8 = 0;
                                while (this.<typeRefIndex>5__8 < this.<typeRefCount>5__7)
                                {
                                    this.<typeRefNamePtr>5__9 = IntPtr.Zero;
                                    NativeMethods.ThrowOnFailure(this.<metaDataImport>5__4.GetTypeRefProps(this.<typeRefs>5__6[this.<typeRefIndex>5__8], out this.<resolutionScopeToken>5__b, this.<typeRefNamePtr>5__9, 0, out this.<typeRefNameLength>5__a));
                                    if (this.<typeRefNameLength>5__a <= 0)
                                    {
                                        goto Label_0494;
                                    }
                                    this.<typeRefName>5__c = string.Empty;
                                    this.<typeRefNamePtr>5__9 = Marshal.AllocCoTaskMem((int) (2 * (this.<typeRefNameLength>5__a + 1)));
                                    try
                                    {
                                        NativeMethods.ThrowOnFailure(this.<metaDataImport>5__4.GetTypeRefProps(this.<typeRefs>5__6[this.<typeRefIndex>5__8], out this.<resolutionScopeToken>5__b, this.<typeRefNamePtr>5__9, this.<typeRefNameLength>5__a, out this.<typeRefNameLength>5__a));
                                    }
                                    finally
                                    {
                                        this.<typeRefName>5__c = Marshal.PtrToStringUni(this.<typeRefNamePtr>5__9);
                                        Marshal.FreeCoTaskMem(this.<typeRefNamePtr>5__9);
                                    }
                                    this.<metaDataAssemblyImport>5__d = this.<metaDataImportObj>5__3 as MetaDataReader.IMetaDataAssemblyImport;
                                    if (this.<metaDataAssemblyImport>5__d == null)
                                    {
                                        throw new InvalidOperationException(string.Format(SR.GetString("Error_MetaDataInterfaceMissing"), this.assemblyLocation, "IMetaDataAssemblyImport"));
                                    }
                                    if (MetaDataReader.TokenTypeFromToken(this.<resolutionScopeToken>5__b) != MetaDataReader.MetadataTokenType.AssemblyRef)
                                    {
                                        goto Label_0494;
                                    }
                                    this.<publicKeyOrToken>5__f = IntPtr.Zero;
                                    this.<assemblyName>5__11 = IntPtr.Zero;
                                    this.<hashValueBlob>5__13 = IntPtr.Zero;
                                    NativeMethods.ThrowOnFailure(this.<metaDataAssemblyImport>5__d.GetAssemblyRefProps(this.<resolutionScopeToken>5__b, out this.<publicKeyOrToken>5__f, out this.<publicKeyOrTokenSize>5__10, this.<assemblyName>5__11, 0, out this.<assemblyNameSize>5__12, out this.<assemblyMetadata>5__e, out this.<hashValueBlob>5__13, out this.<hashValueSize>5__14, out this.<assemblyRefFlags>5__15));
                                    if (this.<assemblyNameSize>5__12 > 0)
                                    {
                                        this.<assemblyName>5__11 = Marshal.AllocCoTaskMem((int) (2 * (this.<assemblyNameSize>5__12 + 1)));
                                    }
                                    if (this.<assemblyMetadata>5__e.localeSize > 0)
                                    {
                                        this.<assemblyMetadata>5__e.locale = Marshal.AllocCoTaskMem((int) (2 * (this.<assemblyMetadata>5__e.localeSize + 1)));
                                    }
                                    this.<>1__state = 3;
                                    if ((this.<assemblyNameSize>5__12 > 0) || (this.<assemblyMetadata>5__e.localeSize > 0))
                                    {
                                        NativeMethods.ThrowOnFailure(this.<metaDataAssemblyImport>5__d.GetAssemblyRefProps(this.<resolutionScopeToken>5__b, out this.<publicKeyOrToken>5__f, out this.<publicKeyOrTokenSize>5__10, this.<assemblyName>5__11, this.<assemblyNameSize>5__12, out this.<assemblyNameSize>5__12, out this.<assemblyMetadata>5__e, out this.<hashValueBlob>5__13, out this.<hashValueSize>5__14, out this.<assemblyRefFlags>5__15));
                                    }
                                    this.<publicKeyString>5__16 = string.Empty;
                                    for (int i = 0; i < this.<publicKeyOrTokenSize>5__10; i++)
                                    {
                                        this.<publicKeyString>5__16 = this.<publicKeyString>5__16 + string.Format("{0}", Marshal.ReadByte(this.<publicKeyOrToken>5__f, i).ToString("x2"));
                                    }
                                    this.<>2__current = string.Format("{0}, {1}, Version={2}.{3}.{4}.{5}, Culture={6}, PublicKeyToken={7}", new object[] { this.<typeRefName>5__c, Marshal.PtrToStringUni(this.<assemblyName>5__11), this.<assemblyMetadata>5__e.majorVersion, this.<assemblyMetadata>5__e.minorVersion, this.<assemblyMetadata>5__e.buildNumber, this.<assemblyMetadata>5__e.revisionNumber, string.IsNullOrEmpty(Marshal.PtrToStringUni(this.<assemblyMetadata>5__e.locale)) ? "neutral" : Marshal.PtrToStringUni(this.<assemblyMetadata>5__e.locale), string.IsNullOrEmpty(this.<publicKeyString>5__16) ? "null" : this.<publicKeyString>5__16 });
                                    this.<>1__state = 4;
                                    return true;
                                Label_0487:
                                    this.<>1__state = 3;
                                    this.<>m__Finally18();
                                Label_0494:
                                    this.<typeRefIndex>5__8++;
                                }
                            }
                            while (this.<typeRefCount>5__7 > 0);
                            this.<>m__Finally17();
                            break;

                        case 4:
                            goto Label_0487;
                    }
                    return false;
                }
                fault
                {
                    this.System.IDisposable.Dispose();
                }
            }

            [DebuggerHidden]
            IEnumerator<object> IEnumerable<object>.GetEnumerator()
            {
                MetaDataReader.<GetTypeRefNames>d__0 d__;
                if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
                {
                    this.<>1__state = 0;
                    d__ = this;
                }
                else
                {
                    d__ = new MetaDataReader.<GetTypeRefNames>d__0(0);
                }
                d__.assemblyLocation = this.<>3__assemblyLocation;
                return d__;
            }

            [DebuggerHidden]
            IEnumerator IEnumerable.GetEnumerator()
            {
                return this.System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator();
            }

            [DebuggerHidden]
            void IEnumerator.Reset()
            {
                throw new NotSupportedException();
            }

            void IDisposable.Dispose()
            {
                switch (this.<>1__state)
                {
                    case 1:
                    case 3:
                    case 4:
                        try
                        {
                            switch (this.<>1__state)
                            {
                                case 3:
                                case 4:
                                    try
                                    {
                                    }
                                    finally
                                    {
                                        this.<>m__Finally18();
                                    }
                                    break;
                            }
                        }
                        finally
                        {
                            this.<>m__Finally17();
                        }
                        break;

                    case 2:
                        break;

                    default:
                        return;
                }
            }

            object IEnumerator<object>.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.<>2__current;
                }
            }

            object IEnumerator.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.<>2__current;
                }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct AssemblyMetadata
        {
            public ushort majorVersion;
            public ushort minorVersion;
            public ushort buildNumber;
            public ushort revisionNumber;
            public IntPtr locale;
            public uint localeSize;
            public IntPtr processorIds;
            public uint processorIdCount;
            public IntPtr osInfo;
            public uint osInfoCount;
        }

        private static class Guids
        {
            public const string CLSID_MetaDataDispenser = "E5CB7A31-7512-11d2-89CE-0080C792E5D8";
            public const string IID_IMetaDataAssemblyImport = "EE62470B-E94B-424e-9B7C-2F00C9249F93";
            public const string IID_IMetaDataDispenser = "809C652E-7396-11d2-9771-00A0C9B4D50C";
            public const string IID_IMetaDataImport = "7DAC8207-D3AE-4c75-9B67-92801A497D44";
        }

        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("EE62470B-E94B-424e-9B7C-2F00C9249F93")]
        private interface IMetaDataAssemblyImport
        {
            void GetAssemblyProps();
            int GetAssemblyRefProps([In] uint assemblyRefToken, out IntPtr publicKeyOrToken, out uint sizePublicKeyOrToken, IntPtr assemblyName, [In] uint assemblyNameBufferSize, out uint assemblyNameSize, out MetaDataReader.AssemblyMetadata assemblyMetaData, out IntPtr hashValueBlob, out uint hashValueSize, out uint assemblyRefFlags);
        }

        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("809C652E-7396-11d2-9771-00A0C9B4D50C")]
        private interface IMetaDataDispenser
        {
            void DefineScope();
            int OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] string scopeName, uint openFlags, [In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object unknown);
            void OpenScopeOnMemory();
        }

        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
        private interface IMetaDataImport
        {
            void CloseEnum([In] IntPtr enumHandle);
            void CountEnum();
            void ResetEnum();
            void EnumTypeDefs();
            void EnumInterfaceImpls();
            int EnumTypeRefs([In, Out] ref IntPtr enumHandle, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] uint[] rTypeRefs, uint cMax, ref uint typeRefs);
            void FindTypeDefByName();
            void GetScopeProps();
            void GetModuleFromScope();
            void GetTypeDefProps();
            void GetInterfaceImplProps();
            int GetTypeRefProps([In] uint typeRefToken, out uint resolutionScopeToken, IntPtr typeRefName, uint nameLength, out uint actualLength);
        }

        [ComImport, Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8")]
        private class MetaDataDispenser
        {
        }

        private enum MetadataTokenType
        {
            AssemblyRef = 0x23000000,
            ModuleRef = 0x1a000000
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct OsInfo
        {
            private uint osPlatformId;
            private uint osMajorVersion;
            private uint osMinorVersion;
        }
    }
}

